#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>

#include "include/servHelper.h"
#include "include/filesContent.h"
#include "include/parser.h"
#include "include/data.h"
#include "include/divId.h"
#include "include/acsLogger.h"

modelNameS *mod_name_s;
deviceId *dev_id;
getNewParamValues get_new_val;
int noSqlError;


/*void write_to_file( char* fileCont )
{
  FILE *p = NULL;
  char *file = "paramName_2760.xml";
  //char buffer[80] = "Don't look for endings when you need a beginning.";
  size_t len = 0;
  p = fopen(file,"aw");
  if (p== NULL) {
  printf("Error in opening a file.. %s", file);
  }
  len = strlen(fileCont);
  fwrite(fileCont, len, 1, p);
  fclose(p);
  printf("\nWritten Successfuly in the file.\n");

}*/

int sendall(char response_xml_file[FILE_MSG_SIZE])
{
   int total = 0;
   memset(xmlFile,0,FILE_MSG_SIZE);
   strcpy(xmlFile,(char*)concatHeadAndXml( getOkHeader( response_xml_file ),response_xml_file ));

    while(total < strlen(xmlFile))
    {
        sendFile = send(i,xmlFile,strlen(xmlFile),0) ;
        if(sendFile == -1) { break; }
        total += sendFile;
    }
    
     if(!sendFile) 
       logtr("ACS Server:","Can not send DATA", ERROR, conferr);
     
    return (sendFile == -1 ? -1 : total);
}

/**
  Function Name     : send_response 
  Input Paramaters  : response_xml_file array
  Output Paramaters : NONE 
  Result            : sending request through socket
  Description       : send xml file 
*/
void send_response(char response_xml_file[FILE_MSG_SIZE])
{
 memset(xmlFile,0,FILE_MSG_SIZE);
 strcpy(xmlFile,(char*)concatHeadAndXml( getOkHeader( response_xml_file ),response_xml_file ));
 sendFile = send(i,xmlFile,strlen(xmlFile),0) ;
 if(!sendFile) 
      logtr("ACS Server:","Can not send DATA", ERROR, conferr);
}

/**
  Function Name     : read_from_client 
  Input Paramaters  : file description
  Output Paramaters : NONE 
  Result            : sending request through socket
  Description       : read data from client
*/
int read_from_client( int fileDesc )
{
  int nbytes;
  memset( buffer,0,READ_MSG_SIZE );
  nbytes = recv(fileDesc, buffer, READ_MSG_SIZE,0);//reade data from client

  if( nbytes <= 0 )
  {
    logtr("ACS Server:","Wait Data from TR069 Client ", ERROR, conferr);
   // printf("\nNo data from client");
   // perror ("Read ...");
    return -1;
   }
   else
   {
     strcat(fileCBuff[fileDesc].fileContBuff,buffer);
     memset(buffer,0,READ_MSG_SIZE);
      return 0;
    }
}

/**
  Function Name     : send_recive_socket 
  Input Paramaters  : NONE
  Output Paramaters : NONE 
  Result            : send && recive data
  Description       : send && recive soap xml files through socket
*/

void send_recive_socket( int i )
{
  if( read_from_client(i) < 0 )
  {
	CLOSECONNECTION: 
	close(i);
	FD_CLR (i,&active_fd_set);
	//printf("\nClose connection ......\n");
	
  }
  else 
  {  
    if( ( ONE_BOOT == 0 || ZERO_BOOTSTRAP == 0 ) && END_XML_FILE  )
    {
      //printf("\nONE_BOOT || ZERO_BOOTSTRAP \n");
      sendall( (char*)getInformResponse( informResponse ) ); 
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      
     //goto CLOSECONNECTION;
    }
		    
    else if( TWO_PERIODIC == 0 && END_XML_FILE  )
    {
      //printf("\nTWO_PERIODIC\n");
      sendall( (char*)getInformResponse( informResponse ) ); 
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      out_get_param_value0 = 1;
    }

    else if( ZERO_CONTENT > 0 )
    {
 	//printf(" \n ZERO_CONTENT \n ");
	sendall( (char*) get_model_name );
	memset(xmlFile,0,FILE_MSG_SIZE);
        memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
	out_get_param_value0 = 1;
    }
    else if( GET_RPC_METHODS_RESP > 0  )
    {
      sendall( (char*)get_model_name );
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      out_get_param_value0 = 1;  
    }
    
    else if( GET_PARAM_VALUE_RESPONSE > 0 && END_XML_FILE  &&   FIND_FIRST_MODEL_PARAM_NAME > 0 && out_get_param_value0 == 1  )
    {  
     //printf("\n GET_PARAM_VALUE_RESPONSE \n");
    char cpy_getParamValue[FILE_MSG_SIZE];
    memset(cpy_getParamValue,0,FILE_MSG_SIZE);
    strcpy(cpy_getParamValue,create_getParam_name_value_xml( get_param_value_string,get_param_value,MODEL_NAME_FIRST ));
      sendall( cpy_getParamValue );
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      out_get_param_value0 = 0;
      out_get_param_value1 = 1;
    }
    
   else if( GET_PARAM_VALUE_RESPONSE > 0 && END_XML_FILE  && out_get_param_value1 == 1  ) 
    { 
      int j;
      for(j = 0;j < number_of_values;j++ ){
        memset(fileCBuff[i].get_val[j].getValueStr,0,sizeof(fileCBuff[i].get_val[j].getValueStr));
	    memset(fileCBuff[i].get_names[j].getNameStr,0,sizeof(fileCBuff[i].get_names[j].getNameStr));
      }

      getValues( fileCBuff[i].get_val,fileCBuff[i].fileContBuff);
      getNames( fileCBuff[i].get_names,fileCBuff[i].fileContBuff); 

      dev_id = (deviceId*)malloc(sizeof(deviceId));
      if(strcmp(MODEL_NAME,SERIAL) != 0 || strcmp(SERIAL,MANUFACT) != 0 || strcmp(MANUFACT,OUI) != 0)
      {
       init_dev_id( MODEL_NAME,SERIAL,MANUFACT,OUI,PRODUCT_CLASS,dev_id );      
	if( check_model_name( MODEL_NAME ) == SUCCESS )
	{
	    if( number_of_values != 1 && !noSqlError )
	    {
	      if( check_device_id( SERIAL ) != SUCCESS  )
		set_device_db(SERIAL,MANUFACT,OUI,PRODUCT_CLASS,MODEL_NAME );

		set_get_value_db( fileCBuff[i].get_names,fileCBuff[i].get_val,get_new_val,MODEL_NAME,SERIAL);
	      
		notChange = (char*)malloc(2048);
		memset(notChange,0,2048);

	      strcpy(notChange,create_set_value_xml(param_value_struct,setValue,SERIAL)  );//?????????????????????????????????????????????????????

	      if( strlen( notChange ) > 4 )
	      sendall(( char* )notChange );	  
	      
	      out_get_param_value1 = 0;
	      
	      if( check_fw_status( dev_id->serialNumber ) == 1 )
		goto DOWNLOAD;
	      
	      if( strlen( notChange ) < 5 ) 
		goto REBOOTSECTOR;
	    }
	}
	else
	{
	  set_unknow_model_name( SERIAL,MODEL_NAME );
	  sendall( (char*)getInformResponse( informResponse ) );
	  memset(xmlFile,0,FILE_MSG_SIZE);
          memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
	  goto CLOSECONNECTION;
	}
      
	memset(xmlFile,0,FILE_MSG_SIZE);
	memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      }
      else
	goto CLOSECONNECTION;
    }
    
    else if( SET_PARAM_FAILUR > 0 && END_XML_FILE )
    {
      //printf( "\nSet parameter value failur failurCode = %s",SET_PARAM_FAILUR_NUM ); 
       logtr(SET_PARAM_FAILUR_NUM ,"Set parameter value failur failurCode =", ERROR, conferr);
    }
    
   else if( SET_PARAMETER_VALUES_RESP > 0  && GET_STATUS && END_XML_FILE )
    {
      char answer[10];
      memset(answer,0,10);
      set_value_answer_insert_db( (char*)strncpy(answer,SET_PARAM_ANSWER,1),dev_id->serialNumber );
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      goto REBOOTSECTOR;
    }
    
    else if( FOR_VALUE_CHANGE == 0 )
    {
      //printf("\n FOR_VALUE_CHANGE  \n"); 
      sendall( (char*)getInformResponse( informResponse ) );
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      goto CLOSECONNECTION; 

    }
    
    else if( c_reboot == 10 )
    {
      REBOOTSECTOR:
      if( cpe_reboot( dev_id->serialNumber ) == 1 )
	{
	  memset(xmlFile,0,FILE_MSG_SIZE);
	  sendall( reboot );
	  set_cpe_reboot_db( dev_id->serialNumber );
	}
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      free(dev_id);
      goto CLOSECONNECTION;
    }
    
    else if( c_download == 10 )
    {
      DOWNLOAD:
      memset(have_fw_upgrade,0,sizeof(have_fw_upgrade));
      strcpy( have_fw_upgrade,(char*)get_check_and_fw( fw_upgrade,dev_id->serialNumber ) );

     if( strlen( have_fw_upgrade ) > 4 )
     { 
      sendall(  have_fw_upgrade  );
      done_fw_upgrade(1,dev_id->serialNumber );
     }
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      free(dev_id);
     goto CLOSECONNECTION;
    }
    
     else if( GET_REBOOT == 0 )
    {
      //printf("\n M Reboot \n"); 
      sendall( ( char* )getInformResponse( informResponse ) );
      memset(xmlFile,0,FILE_MSG_SIZE);
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
      goto CLOSECONNECTION;
    }
     
     else if( M_DOWNLOAD == 0 && END_XML_FILE )
     {
      //printf("\n M_DOWNLOAD \n"); 
      sendall( (char*)getInformResponse( transfer_complete_response ) );
      memset( xmlFile,0,FILE_MSG_SIZE );
      memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
//       goto CLOSECONNECTION;
     }
     
     else if( TRANSFER_COMPLETE )
     {
       //printf("\n TRANSFER_COMPLETE \n"); 
       sendall( (char*)getInformResponse( informResponse ) );
       memset( xmlFile,0,FILE_MSG_SIZE );
       memset(fileCBuff[i].fileContBuff,0,FILE_MSG_SIZE);
       goto CLOSECONNECTION;
     }
    else
    { 
      if(noSqlError)
	goto CLOSECONNECTION;
        //printf("."); 
    }		  
  }

}

